package mythread;

/**
 * @Auther: cty
 * @Date: 2020/1/7 1:59
 * @Description: 不安全2-1
 * 不安全概述：
 * 非共享资源时，一个线程将主内存中的资源拷贝到自己的工作空间还未来得及“改”回主内存，其他线程又将该资源从主内存拷贝到自己的工作空间进行访问（读 或 改）
 * 三个窗口都从主内存拷贝票数到自己的工作空间进行操作
 * @version: 1.0
 */
public class Hc_UnsafeTest2_1 implements Runnable{
    private static volatile int ticketsNum = 99;  //剩余车票数

    @Override
    public void run() {
        while(true){
            if(ticketsNum <= 0){  //【判断】
                break;
            }
            // 模拟网络延时-无论怎么延时都不会影响结果
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName()+"售出了 "+ticketsNum+" 号票");  //【打印】
            // 模拟网络延时-无论怎么延时都不会影响结果
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName()+"剩余 "+--ticketsNum+"张票");  //【修改】
        }
    }

    public static void main(String[] args) {
        //三份任务
        Hc_UnsafeTest2_1 ticket1 = new Hc_UnsafeTest2_1();
        Hc_UnsafeTest2_1 ticket2 = new Hc_UnsafeTest2_1();
        Hc_UnsafeTest2_1 ticket3 = new Hc_UnsafeTest2_1();
        //三个代理
        new Thread(ticket1,"窗口1").start();  //第一个new Thread开辟工作空间1
        new Thread(ticket2,"窗口2").start();  //第一个new Thread开辟工作空间2
        new Thread(ticket3,"窗口3").start();  //第一个new Thread开辟工作空间3

        while (true){
            if(ticketsNum <= 0){  //【判断】
                break;
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(ticketsNum);
        }
    }
}

/*
...
窗口3售出了 2 号票
窗口2售出了 2 号票
窗口1售出了 2 号票
窗口3剩余 1张票
窗口2剩余 1张票
窗口1剩余 1张票
窗口3售出了 1 号票
窗口1售出了 1 号票
窗口2售出了 1 号票
窗口3剩余 0张票
窗口2剩余 0张票
窗口1剩余 0张票
*/